﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package com.zynga.skelly.render {
    import flash.events.*;
    import flash.display.*;
    import flash.utils.*;
    import de.polygonal.ds.*;
    import com.zynga.skelly.animation.*;

    public class RenderManager extends EventDispatcher {

        public static var animationSchedulesByFPS:Dictionary = new Dictionary(true);
        private static var beginFrameTimeMs:int;
        private static var beginFrameDeltaMs:int;
        private static var m_mainRenderer:IRenderer;
        private static var m_stage:Stage;
        private static var m_beginFrameTimer:Timer;
        private static var m_bShouldRender:Boolean;
        private static var m_iLastFrameBeginTime:int;
        private static var m_uFrameCount:uint = 0;
        private static var m_dictFrameBeginUpdaters:Dictionary = new Dictionary();
        private static var m_delayedFunctionCalls:Array = new Array();
        private static var eventDispatcher:EventDispatcher = new EventDispatcher();
        private static var m_animSchedules:SLinkedList = new SLinkedList();
        private static var iter:SListIterator;
        private static var _frameRate:int = 60;
        private static var m_useFrameRenders:Boolean = false;
        private static var m_dontRunScheduledAnims:Boolean = false;
        private static var rates:Array = [1, 12, 20];

        public static function init(_arg1:IRenderer, _arg2:Stage, _arg3:int=-1, _arg4:Boolean=false):void{
            m_mainRenderer = _arg1;
            m_useFrameRenders = _arg4;
            m_stage = _arg2;
            frameRate = ((_arg3 < 0)) ? 60 : _arg3;
            m_beginFrameTimer = new Timer(0, 1);
            m_beginFrameTimer.addEventListener(TimerEvent.TIMER, handleBeginFrameTimer, false, 0, true);
            m_stage.addEventListener(Event.ENTER_FRAME, handleEnterFrame, false, 0, true);
            m_stage.addEventListener(Event.RENDER, handleRenderEvent, false, 9999, true);
            m_stage.invalidate();
            trace(("@RenderManager::init..." + getTimer()));
        }
        public static function set dontRunScheduledAnimations(_arg1:Boolean):void{
            m_dontRunScheduledAnims = _arg1;
        }
        public static function get dontRunScheduledAnimations():Boolean{
            return (m_dontRunScheduledAnims);
        }
        public static function set renderer(_arg1:IRenderer):void{
            m_mainRenderer = _arg1;
        }
        public static function set frameRate(_arg1:int):void{
            _frameRate = (m_stage.frameRate = _arg1);
            initAnimSchedules();
        }
        public static function get frameRate():int{
            return (_frameRate);
        }
        private static function initAnimSchedules():void{
            var _local1:int;
            var _local2:int;
            var _local3:int;
            var _local4:int;
            for each (_local1 in rates) {
                _local2 = Math.ceil((frameRate / _local1));
                _local3 = Math.ceil((1000 / _local1));
                _local4 = Math.ceil((frameRate / _local2));
                if (!animationSchedulesByFPS[_local4]){
                    trace("creating animationSchedule fps = ", _local1, ", FramesPerProcess = ", _local2, ", FrameTimeMs = ", _local3, ", numProcessingLists = ", _local4);
                    animationSchedulesByFPS[_local4] = m_animSchedules.append(new AnimationSchedule(_local2, _local3)).data;
                };
            };
            iter = m_animSchedules.getListIterator();
        }
		
		/**
		 * 根据每秒的帧数从AnimationSchedule中找到对应的IAnimated
		 */
        public static function findNearestByFps(_arg1:int, _arg2:IAnimated):AnimationSchedule{
            var _local4:AnimationSchedule;
            var _local5:AnimationSchedule;
            var _local8:int;
            var _local3:int = Math.ceil((frameRate / _arg1));
            iter.start();
            var _local6:int = int.MAX_VALUE;
            var _local7 = 1000;
            while (iter.data != null) {
                _local5 = iter.data;
                _local8 = Math.abs((_local5.framesPerProcess - _local3));
                if (_local8 < _local6){
                    _local4 = _local5;
                    _local6 = _local8;
                };
                _local5.remove(_arg2);
                iter.forth();
            };
            return (_local4);
        }
        public static function addAnimationByFPS(_arg1:int, _arg2:IAnimated):AnimationList{
            var _local3:AnimationSchedule = findNearestByFps(_arg1, _arg2);
            if (_local3){
                return (_local3.add(_arg2));
            };
            return (null);
        }
        public static function removeAnimationByFPS(_arg1:int, _arg2:IAnimated):void{
            var _local3:AnimationSchedule = findNearestByFps(_arg1, _arg2);
        }
        private static function processAnimationSchedules(_arg1:int):void{
            var _local2:AnimationSchedule;
            if (m_dontRunScheduledAnims){
                return;
            };
            iter.start();
            while (iter.data != null) {
                _local2 = iter.data;
                _local2.process(_arg1);
                iter.forth();
            };
        }
        public static function get framecount():uint{
            return (m_uFrameCount);
        }
        public static function addDelayedFunctionCall(_arg1:Function):void{
            m_delayedFunctionCalls.push(_arg1);
        }
        public static function addFrameBeginUpdater(_arg1:IRenderer):void{
            m_dictFrameBeginUpdaters[_arg1] = _arg1;
        }
        public static function removeFrameBeginUpdater(_arg1:IRenderer):void{
            delete m_dictFrameBeginUpdaters[_arg1];
        }
        static function handleRenderEvent(_arg1=null):void{
            if (!m_useFrameRenders){
                m_bShouldRender = true;
                m_beginFrameTimer.start();
                if ((m_mainRenderer is INotifyBeforeRender)){
                    (m_mainRenderer as INotifyBeforeRender).onNotifyBeforeRender();
                };
            };
        }
        private static function handleEnterFrame(_arg1:Event):void{
            if (m_useFrameRenders){
                m_bShouldRender = true;
            };
            if ((m_mainRenderer is INotifyBeforeRender)){
                (m_mainRenderer as INotifyBeforeRender).onNotifyBeforeRender();
            };
            if (m_bShouldRender){
                m_stage.invalidate();
                m_bShouldRender = false;
                FrameRateGraph.annotate(2261060);
                doRender();
            };
        }
        private static function handleBeginFrameTimer(_arg1:Event):void{
            if (m_bShouldRender){
                m_stage.invalidate();
                m_bShouldRender = false;
                FrameRateGraph.annotate(0xDD00);
                doRender();
            };
        }
        private static function doRender():void{
            var _local3:*;
            var _local4:IRenderer;
            var _local5:Boolean;
            beginFrameTimeMs = getTimer();
            var _local1:int = (beginFrameTimeMs - m_iLastFrameBeginTime);
            m_uFrameCount++;
            var _local2:Function = m_delayedFunctionCalls.shift();
            if (_local2 != null){
                _local2();
            };
            for (_local3 in m_dictFrameBeginUpdaters) {
                _local4 = (_local3 as IRenderer);
                if (_local4){
                    _local5 = _local4.onRender(beginFrameTimeMs, _local1);
                    if (!_local5){
                        delete m_dictFrameBeginUpdaters[_local3];
                    };
                } else {
                    delete m_dictFrameBeginUpdaters[_local3];
                };
            };
            if (m_mainRenderer){
                m_mainRenderer.onRender(beginFrameTimeMs, _local1);
            };
            processAnimationSchedules(beginFrameTimeMs);
            m_iLastFrameBeginTime = beginFrameTimeMs;
        }

    }
}//package com.zynga.skelly.render 
